package com.gdepri.cabelwellserver.handler;

import com.gdepri.cabelwellserver.entity.CabelMessage;
import com.gdepri.cabelwellserver.tools.ByteFun;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

public class ByteMsgEncoder {
    private Logger logger = LoggerFactory.getLogger(ByteMsgEncoder.class);
    ByteFun byteFun = new ByteFun();
    //根据传入的cabelMessage对象，生成对应的字节数组
    public  byte[] encode(CabelMessage cabelMessage) {
        int arrLength = cabelMessage.getDataLength() + 8;
        byte[] cabelMessageByteArr = new byte[arrLength];

        //第一部分 起始字
        cabelMessageByteArr[0]=cabelMessage.getStartWord();
        logger.info("编码起始字："+cabelMessageByteArr[0]);
        int counter = 1;
        logger.info("@@@@@counter"+counter++);


        //第二部分 长度   int转成2字节的byte,数据不能有丢失
        //cabelMessageByteArr[1-2]
        byte[] lengthBytes = byteFun.intTo2Bytes(cabelMessage.getLength());
        logger.info("要把长度变成二进制数字："+cabelMessage.getLength()+"二进制的数组是："+Arrays.toString(lengthBytes));
        System.arraycopy(lengthBytes,0,cabelMessageByteArr,1,2);
        logger.info("编码长度："+ Arrays.toString(lengthBytes));
        logger.info("@@@@@counter"+counter++);
        logger.info("@@@@@counter"+counter++);

        //第三部分 控制字  拼接出1字节8比特的二进制数，然后转成byte
        //cabelMessageByteArr[3]
        String direction = cabelMessage.getDirection();//bit7,就这一位
        int packNum = cabelMessage.getPackNum();//bit 5-6,两位
        int funcCode = cabelMessage.getFuncCode();//bit 0-4,五位
        String pack = byteFun.int2binary2(packNum);
        String func = byteFun.int2binary5(funcCode);
        String ctrlBinary = direction+pack+func;
        byte ctrl = (byte)Integer.parseInt(ctrlBinary,2);
        cabelMessageByteArr[3]=ctrl;
        logger.info("控制字："+cabelMessageByteArr[3]);
        logger.info("@@@@@counter"+counter++);

        //第四部分 地址   int转成2字节的bute,数据不能有丢失
        //cabelMessageByteArr[4-5]
        byte[] addressBytes = byteFun.intTo2Bytes(cabelMessage.getAddress());
        System.arraycopy(addressBytes,0,cabelMessageByteArr,4,2);
        logger.info("地址大小："+addressBytes.length);
        logger.info("@@@@@counter"+counter++);
        logger.info("@@@@@counter"+counter++);

        //第五部分 数据    data直接copy
        //把datacopy到cabelMessageByteArr[6到6+datalen]
        if(cabelMessage.getData()!=null && cabelMessage.getData().length>0){
            System.arraycopy(cabelMessage.getData(), 0, cabelMessageByteArr, 6, cabelMessage.getDataLength());
            logger.info("数据大小："+cabelMessage.getDataLength());
            logger.info("@@@@@counter"+counter++);
            logger.info("@@@@@counter"+counter++);
            logger.info("@@@@@counter"+counter++);
            logger.info("@@@@@counter"+counter++);
        }


        //第六部分 校验字
        //看看校验字的规则，然后加进去
        //从控制字开始到数据的最后一个byte为止,当做unsigned byte相加。cs是个unsigned char,也就是一个字节8位
        int i = byteFun.checkByteArr(cabelMessageByteArr);
        logger.info("校验字的值为："+i);
        cabelMessageByteArr[arrLength-2] = (byte)i;
        logger.info("编码校验字："+cabelMessageByteArr[arrLength-2]);
        logger.info("@@@@@counter"+counter++);

        //第七部分 结束字
        cabelMessageByteArr[arrLength-1]=cabelMessage.getEndWord();
        logger.info("编码结束字："+cabelMessageByteArr[arrLength-1]);
        logger.info("@@@@@counter"+counter++);

        logger.info("cabelMessageByteArr大小"+cabelMessageByteArr.length);
        return cabelMessageByteArr;
    }
}
